﻿exchanger = function () {
    var self = this;
    var templates = {
        market: $("#tplMarket").html(),
        order: $("#tplOrder").html(),
        contract: $("#tplContract").html(),
        contractSummary: $("#tplContractSummary").html()
    },
    $objs = {
        openOrder: {
            add: $("#boxAddOrder"),
            order: $("#addOrder"),
            orderTab: $("#addOrderTab"),
            orderTabMarket: $("#addOrderTab li:eq(0) a"),
            orderTabLimit: $("#addOrderTab li:eq(1) a"),
            setStopPrice: $("#boxSetStopPrice"),
            setPrice: $("#boxSetPrice"),
            contract: $("#boxContract"),
            confirm: $("#boxAddOrderConfirm"),
            success: $("#boxAddOrderSuccess"),
            IsStopLossPrice: $("input.IsStopLossPrice"),
            IsStopProfitPrice: $("input.IsStopProfitPrice"),
            StopLossPrice: $("input.StopLossPrice"),
            StopProfitPrice: $("input.StopProfitPrice"),
            IsConfirmOrder: $("#chkConfirmOrder")
        },
        tabOrder: $("#tabOrder"),
        tabContract: $("#tabContract"),
        account: $("#boxAsset"),
        goods: $("#boxGoods"),
        marketItem: $("#boxMarketItem"),
        market: $("#listMarket tbody"),
        ordering: $("#ordering tbody"),
        ordered: $("#ordered tbody"),
        orderCancel: $("#orderCancel tbody"),
        contract: $("#contractItems tbody"),
        contractSummary: $("#contractSummary tbody"),
        chart: null,
        modalChart: $("#modalChart")
    },
        datas = {
            ui: { PositionType: resources.ContractPositionType.Open, PositionTypeTitle: "建仓" },
            settings: {},
            account: {},
            market: {},
            order: {},
            contract: {},
            contractSummary: {},
            addOrder: {},
            setMarket: {},
            selectedMarket: {},
            selectedGoodsID: null
        };

    this.init = function (_settings) {
        initSignalR();

        DataBind.bind($objs.openOrder.order, datas.ui);

        $("body").on("click", ".cancelOrder", function () {//撤消委托
            var id = $(this).parents("tr").attr("id");
            jconfirm(R("OrderDeleteConfirm", "亲爱的用户，您确定要撤消这个委托吗？"), function () {
                cancelOrder(id);
            });
        }).on("click", ".openContract,.buyPrice,.sellPrice", function () {//新建建仓委托
            if ($(this).hasClass("openContract")) {
                $objs.openOrder.orderTabLimit.click();
            }
            else {
                $objs.openOrder.orderTabMarket.click();
            }
            datas.ui.PositionType = resources.ContractPositionType.Open;

            addOrder(this);
        }).on("click", ".closeContract,.stopLossPrice,.stopProfitPrice", function () {//新建平仓委托
            if ($(this).hasClass("closeContract")) {
                $objs.openOrder.orderTabMarket.click();
            }
            else {//设置持仓的止损止盈
                $objs.openOrder.orderTabLimit.click();
                $objs.openOrder.orderTab.hide();

                if ($(this).hasClass("stopLossPrice")) {

                }
            }

            datas.ui.PositionType = resources.ContractPositionType.Close;

            addOrder(this);
        }).on("click", ".close-all-contract", function () {//全平持仓
            var type = $(this).attr("data-type") || 0;
            var msg = type == 0 ? "确定要将您的持仓全部平仓吗？" : (type == 1 ? "确定要将您的 买仓 全部平仓吗？" : "确定要将您的 卖仓 全部平仓吗？");

            jconfirm(msg, function () {
                closeAllContract(type);
            })

        }).on("click", ".cancel-all-order", function () {//全撤委托
            var type = $(this).attr("data-type") || 0;
            var msg = type == 0 ? "确定要将您的委托全部撤消吗？" : (type == 1 ? "确定要将您的 买入委托 全部撤消吗？" : "确定要将您的 卖出委托 全部撤消吗？");

            jconfirm(msg, function () {
                cancelAllOrder(type);
            })

        }).on("click", "#submitAddOrder", function () {//提交委托
            if ($objs.openOrder.IsConfirmOrder.prop("checked") && !$objs.openOrder.IsConfirmOrder.data("confirmed")) {
                showAddOrderConfirm();
                $objs.openOrder.add.hide();
                $objs.openOrder.confirm.show();

                $objs.openOrder.IsConfirmOrder.data("confirmed", true);
            }
            else {
                $objs.openOrder.IsConfirmOrder.data("confirmed", false);
                submitAddOrder();
            }
        }).on("click", "#listMarket tbody tr", function () {
            selectMarket($(this).attr("id"));
        }).on("click", "#chkConfirmOrder", function () {
            datas.settings.IsConfirmOrder = $(this).prop("checked");
            signalR.server.setIsConfirmOrder(datas.settings.IsConfirmOrder).fail(function (error) {
                console.log('Invocation of SetIsConfirmOrder failed. Error: ' + error);
            });
        }).on("click", "#listMarket .openChart", function () {
            $objs.modalChart.find(".modal-body div.left").append($("#layoutMarketItem"));
            $objs.modalChart.find(".modal-body div.right").append($("#layoutGoods"));
            $objs.modalChart.find(".modal-title").html($objs.marketItem.find(".pancel-goods").html());
            $objs.modalChart.find(".pancel-goods").hide();
            $objs.modalChart.modal("show");
        });

        $objs.modalChart.on("hidden.bs.modal", function () {
            $objs.modalChart.find(".pancel-goods").show();
            $("#layoutRight").prepend($("#layoutMarketItem"));
            $("#layoutRight .layoutRightBottom").append($("#layoutGoods"));
        });

        //设置仓的市价或限价
        $objs.openOrder.orderTab.find("a").click(function () {
            initTabUI();
        });

        //开启止损
        $objs.openOrder.IsStopLossPrice.click(function () {
            var checked = $(this).prop("checked");
            $objs.openOrder.StopLossPrice.val("").prop("disabled", !checked);
        });
        //开启止盈
        $objs.openOrder.IsStopProfitPrice.click(function () {
            $objs.openOrder.StopProfitPrice.val("").prop("disabled", !$(this).prop("checked"));
        });

        //设置最大可建仓数量
        $("#boxAddOrder .btnMaxUsableQty").click(function () {
            datas.addOrder.OrderQty = datas.addOrder.MaxUsableQty;
        });

        $("input.TouchSpin").TouchSpin({
            verticalbuttons: true,
            verticalupclass: 'fa fa-sort-up',
            verticaldownclass: 'fa fa-sort-down'
        }).on("change", function () {
            var $this = $(this);
            datas.addOrder[$this.attr("data-key")] = $this.val();
        });
    }

    //初始化委托界面
    initUI = function () {
        datas.ui.PositionTypeTitle = datas.ui.PositionType == resources.ContractPositionType.Open
            ? "建仓"
            : (getOrderType() == resources.ContractOrderPriceType.LimitPrice ? "设置止损止盈" : "平仓");

        $objs.openOrder.add.show();
        $objs.openOrder.confirm.hide();
        $objs.openOrder.success.hide();

        $objs.openOrder.IsStopLossPrice.prop("checked", false);
        $objs.openOrder.IsStopProfitPrice.prop("checked", false);
        $objs.openOrder.StopLossPrice.prop("disabled", true);
        $objs.openOrder.StopProfitPrice.prop("disabled", true);

        initTabUI();
    }

    //初始化委托Tab界面
    initTabUI = function () {
        var orderType = getOrderType();
        if (datas.ui.PositionType == resources.ContractPositionType.Close) {
            $objs.openOrder.orderTab.hide();
            orderType == resources.ContractOrderPriceType.LimitPrice
            ? ($objs.openOrder.setStopPrice.show(), $objs.openOrder.setPrice.hide(), $objs.openOrder.contract.show())
            : ($objs.openOrder.setStopPrice.hide(), $objs.openOrder.setPrice.show(), $objs.openOrder.contract.show());
        }
        else {
            $objs.openOrder.orderTab.show();
            orderType == resources.ContractOrderPriceType.LimitPrice
            ? ($objs.openOrder.setStopPrice.show(), $objs.openOrder.setPrice.show(), $objs.openOrder.contract.hide())
            : ($objs.openOrder.setStopPrice.hide(), $objs.openOrder.setPrice.show(), $objs.openOrder.contract.hide());

            if (datas.addOrder.GoodsID) {
                datas.addOrder.MaxUsableQty = getMaxUsableQty(parseFloat(orderType == resources.ContractOrderPriceType.LimitPrice ? datas.addOrder.OrderPrice : datas.addOrder.MarketPrice), getMarketData(datas.addOrder.GoodsID).Goods);
            }
        }
    }

    selectMarket = function (goodsID) {
        var market = getMarketData(goodsID);
        var goods = market.Goods;

        goods.Status = resources.GetGoodsStatus(goods.Status);
        goods.FeeTypeText = resources.GetFeeType(goods.FeeType);
        goods.TradeSpecUnit = goods.TradeSpec + " " + goods.TradeUnit;

        $.extend(datas.selectedMarket, market);

        DataBind.bind($objs.marketItem, datas.selectedMarket);
        DataBind.bind($objs.goods, goods);

        signalR.server.getChartData(goods.GoodsID).done(function (data) {
            buildChart(data);
        }).fail(function (error) {
            console.log('Invocation of getChartData failed. Error: ' + error);
        });

        datas.selectedGoodsID = goodsID;
    }

    //新建委托
    addOrder = function (obj) {
        initUI();
        showAddOrder(obj);
    }

    //全平
    closeAllContract = function (type) {
        console.log(type);
        signalR.server.closeAllContract(parseInt(type)).done(function (data) {
            console.log(data);
            if (data.Result) {
            }
            else {
                jalert(data.Message);
            }
        }).fail(function (error) {
            console.log('Invocation of closeAllContract failed. Error: ' + error);
        });
    }

    //全撤
    cancelAllOrder = function (type) {
        console.log(type);
        signalR.server.cancelAllOrder(parseInt(type)).done(function (data) {
            console.log(data);
            if (data.Result) {
            }
            else {
                jalert(data.Message);
            }
        }).fail(function (error) {
            console.log('Invocation of cancelAllOrder failed. Error: ' + error);
        });
    }

    //撤消委托
    cancelOrder = function (id) {
        console.log(id);
        signalR.server.cancelOrder(parseInt(id)).done(function (data) {
            console.log(data);
            if (data.Result) {
            }
            else {
                jalert(data.Message);
            }
        }).fail(function (error) {
            console.log('Invocation of cancelOrder failed. Error: ' + error);
        });
    }

    //建仓
    showAddOrder = function (obj) {
        var $obj = $(obj);
        var $box = $objs.openOrder.add;
        var goodsID = $obj.parents("tr").attr("data-goods");
        var data = getMarketData(goodsID);
        var type = parseInt($obj.attr("data-type")), contractID = $obj.parents("tr").attr("data-contract");
        var $ContractType = $box.find("[data-key='ContractType']"), $StopLossPrice = $box.find(".StopLossPrice"), $StopLossFeedback = $StopLossPrice.nextAll(".StopLossTip"), $StopProfitPrice = $box.find(".StopProfitPrice"), $StopProfitFeedback = $StopProfitPrice.nextAll(".StopProfitTip");
        var marketPrice = getMarketPrice(type, data), maxUsableQty = getMaxUsableQty(marketPrice, data.Goods);
        var contract = datas.ui.PositionType == resources.ContractPositionType.Open ? null : (contractID ? getContractData(contractID) : getContractSummaryData(goodsID));

        $ContractType.removeClass("up").removeClass("dn").addClass(resources.GetContractTypeColor(type));

        datas.addOrder = {
            GoodsID: data.GoodsID,
            GoodsName: data.GoodsName,
            MinOrderQty: data.Goods.MinOrderQuantity,
            MaxOrderQty: datas.ui.PositionType == resources.ContractPositionType.Open ? data.Goods.MaxOrderQuantity : contract.Quantity,
            MaxUsableQty: datas.ui.PositionType == resources.ContractPositionType.Open ? maxUsableQty : contract.Quantity,
            Type: type,
            ContractID: contractID,
            ContractType: resources.GetContractWay(type),
            MarketPrice: marketPrice,
            OrderPrice: marketPrice,
            OrderPriceUnit: type === resources.ContractType.Buy ? ">" : "<",
            OrderQty: 1,
            StopLossPrice: "",
            StopProfitPrice: "",
            StopLossPriceBase: getStopLossPriceBase(type, data.Goods, marketPrice),
            StopProfitPriceBase: getStopProfitPriceBase(type, data.Goods, marketPrice),
            StopLossPriceUnit: type === resources.ContractType.Buy ? "<" : ">",
            StopProfitPriceUnit: type === resources.ContractType.Buy ? ">" : "<"
        };

        if (datas.ui.PositionType == resources.ContractPositionType.Close) {
            //持仓明细
            if (contractID) {
                $.extend(datas.addOrder, {
                    ContractID: contract.ContractID, ContractQty: contract.Quantity, ContractPrice: contract.Price,
                    StopLossPrice: contract.StopLossPrice == 0 ? "" : contract.StopLossPrice,
                    StopProfitPrice: contract.StopProfitPrice == 0 ? "" : contract.StopProfitPrice,
                    StopLossPriceBase: getStopLossPriceBase(type, data.Goods, contract.Price),
                    StopProfitPriceBase: getStopProfitPriceBase(type, data.Goods, contract.Price),
                });
            }
            else {//持仓汇总
                $.extend(datas.addOrder, {
                    ContractID: contract.ContractID, ContractQty: contract.Quantity, ContractPrice: contract.Price
                });
            }

            datas.addOrder.OrderQty = contract.Quantity;
        }
        if (datas.addOrder.StopLossPrice > 0) {
            $objs.openOrder.IsStopLossPrice.click();
        }
        if (datas.addOrder.StopProfitPrice > 0) {
            $objs.openOrder.IsStopProfitPrice.click();
        }

        console.log(datas.addOrder);

        DataBind.bind($box, datas.addOrder).watch(function (ev) {
            if (ev.type == "databind-dom-change") {
                switch (ev.data.key) {
                    case "OrderPrice": {
                        var price = parseFloat(ev.data.newValue);
                        datas.addOrder.StopLossPriceBase = getStopLossPriceBase(type, data.Goods, price);
                        datas.addOrder.StopProfitPriceBase = getStopProfitPriceBase(type, data.Goods, price);
                        if (datas.ui.PositionType == resources.ContractPositionType.Open && getOrderType() == resources.ContractOrderPriceType.LimitPrice) {
                            datas.addOrder.MaxUsableQty = getMaxUsableQty(parseFloat(ev.data.newValue), data.Goods);
                        }
                        break;
                    }
                    case "StopLossPrice": {
                        ev.data.newValue == "" ? $StopLossFeedback.hide() : $StopLossFeedback.text((Math.abs(ev.data.newValue / datas.addOrder.OrderPrice - 1) * 100).toFixed(2) + "%").show();
                        break;
                    }
                    case "StopProfitPrice": {
                        ev.data.newValue == "" ? $StopProfitFeedback.hide() : $StopProfitFeedback.text((Math.abs(ev.data.newValue / datas.addOrder.OrderPrice - 1) * 100).toFixed(2) + "%").show();
                        break;
                    }
                }
            }
            else if (ev.type == "databind-model-change") {
                switch (ev.data.key) {
                    case "MarketPrice": {
                        if (datas.ui.PositionType == resources.ContractPositionType.Open && getOrderType() == resources.ContractOrderPriceType.MarketPrice) {
                            datas.addOrder.MaxUsableQty = getMaxUsableQty(parseFloat(ev.data.newValue), data.Goods);
                        }
                    }
                }
            }
        });

        $objs.openOrder.order.modal("show");
    }

    //建仓确认
    showAddOrderConfirm = function () {
        DataBind.bind($objs.openOrder.confirm, datas.addOrder);
    }

    //提交建仓
    submitAddOrder = function () {
        var goodsID, contractType, orderType, tradeType, orderQty, orderPrice, stopLossPrice, stopProfitPrice, contractID;

        goodsID = datas.addOrder.GoodsID;
        contractType = datas.addOrder.Type;
        orderType = getOrderType();
        tradeType = datas.ui.PositionType;
        orderQty = datas.addOrder.OrderQty;
        orderPrice = datas.addOrder.OrderPrice;
        stopLossPrice = $objs.openOrder.IsStopLossPrice.prop("checked") ? parseFloat(datas.addOrder.StopLossPrice) || 0 : 0;
        stopProfitPrice = $objs.openOrder.IsStopProfitPrice.prop("checked") ? parseFloat(datas.addOrder.StopProfitPrice) || 0 : 0;
        contractID = parseInt(datas.addOrder.ContractID) || 0;

        if (checkSubmit(goodsID, contractType, orderType, tradeType, orderQty, orderPrice, stopLossPrice, stopProfitPrice, contractID)) {
            signalR.server.openOrder(goodsID, contractType, orderType, tradeType, orderQty, orderPrice, stopLossPrice, stopProfitPrice, contractID).done(function (data) {
                console.log(data);
                if (data.Result) {
                    $objs.openOrder.order.modal("hide");
                }
                else {
                    $objs.openOrder.add.show();
                    $objs.openOrder.confirm.hide();
                    jalert(data.Message);
                }
            }).fail(function (error) {
                console.log('Invocation of openOrder failed. Error: ' + error);
            });
        }
        else {

        }

    }

    //验证提交
    checkSubmit = function (goodsID, contractType, orderType, tradeType, orderQty, orderPrice, stopLossPrice, stopProfitPrice, contractID) {
        var r = true;
        if (tradeType == resources.ContractPositionType.Close) {
            if (orderType == resources.ContractOrderPriceType.LimitPrice) {
                if (datas.addOrder.StopLossPrice * 1 == 0 && datas.addOrder.StopProfitPrice * 1 == 0 && !$objs.openOrder.IsStopLossPrice.prop("checked") && !$objs.openOrder.IsStopProfitPrice.prop("checked")) {
                    jalert("请设置止损或止盈价格。");
                    r = false;
                }
            }
            else {
                if (orderQty > datas.addOrder.MaxOrderQty || orderQty < datas.addOrder.MinOrderQty || orderQty > datas.addOrder.MaxUsableQty) {
                    jalert("无效的数量，请重新输入。");
                    r = false;
                }
            }
        }
        else {
            if (orderQty > datas.addOrder.MaxOrderQty || orderQty < datas.addOrder.MinOrderQty || orderQty > datas.addOrder.MaxUsableQty) {
                jalert("无效的数量，请重新输入。");
                r = false;
            }

            if (orderType == resources.ContractOrderPriceType.LimitPrice) {
                if (contractType == resources.ContractType.Buy && orderPrice <= datas.addOrder.MarketPrice) {
                    jalert("无效的价格，价格必须大于买入现价。");
                    r = false;
                }
                else if (contractType == resources.ContractType.Sell && orderPrice >= datas.addOrder.MarketPrice) {
                    jalert("无效的价格，价格必须小于卖出现价。");
                    r = false;
                }
            }
            else {

            }
        }

        if (orderType == resources.ContractOrderPriceType.LimitPrice) {
            if ($objs.openOrder.IsStopLossPrice.prop("checked")) {
                if (contractType == resources.ContractType.Buy) {
                    if (stopLossPrice >= datas.addOrder.StopLossPriceBase) {
                        jalert("无效的止损价格，请重新设置。");
                        r = false;
                    }
                }
                else {
                    if (stopLossPrice <= datas.addOrder.StopLossPriceBase) {
                        jalert("无效的止损价格，请重新设置。");
                        r = false;
                    }
                }
            }

            if ($objs.openOrder.IsStopProfitPrice.prop("checked")) {
                if (contractType == resources.ContractType.Buy) {
                    if (stopProfitPrice <= datas.addOrder.StopProfitPriceBase) {
                        jalert("无效的止盈价格，请重新设置。");
                        r = false;
                    }
                }
                else {
                    if (stopProfitPrice >= datas.addOrder.StopProfitPriceBase) {
                        jalert("无效的止盈价格，请重新设置。");
                        r = false;
                    }
                }
            }
        }

        return r;
    }

    //初始化资金UI
    initAccountUI = function () {
        var $MoneyRisk = $objs.account.find('td[data-key="MoneyRisk"]');
        if (datas.account.MoneyRisk > 0) {
            $MoneyRisk.removeClass().addClass("dn");
        }
        else {
            $MoneyRisk.removeClass().addClass("up");
        }

        var $CurrentIncome = $objs.account.find('td[data-key="CurrentIncome"]');
        if (datas.account.CurrentIncome < 0) {
            $CurrentIncome.removeClass().addClass("dn");
        }
        else {
            $CurrentIncome.removeClass().addClass("up");
        }

        var $FloatingProfit = $objs.account.find('td[data-key="FloatingProfit"]');
        if (datas.account.FloatingProfit < 0) {
            $FloatingProfit.removeClass().addClass("dn");
        }
        else {
            $FloatingProfit.removeClass().addClass("up");
        }
    }

    refreshChart = function (data) {
        if (data.GoodsID == datas.selectedGoodsID && $objs.chart) {
            var series = $objs.chart.series[0];
            var dt = new Date(data.createTime);
            var pointData = [getUTCByDT(new Date(dt.getFullYear(), dt.getMonth(), dt.getDate(), dt.getHours(), dt.getMinutes(), 0)), data.price];
            series.points.filter(function (v) { return v.x == pointData[0]; }).forEach(function (v) { v.remove(); });
            series.addPoint(pointData);

            $.extend(datas.selectedMarket, data);
        }
    }

    buildChart = function (data) {
        data = eval(data) || [];
        //data = [];

        var lineColor = "#333333";

        new Highcharts.StockChart({
            chart: {
                renderTo: "chart",
                type: 'spline',
                animation: Highcharts.svg, // don't animate in old IE
                marginRight: 10,
                backgroundColor: "rgba(0,0,0, 0.4)",
                events: {
                    load: function () {

                        $objs.chart = $("#chart").highcharts();

                        //// set up the updating of the chart each second
                        //var series = this.series[0];
                        //setInterval(function () {
                        //    var x = (new Date()).getTime(), // current time
                        //        y = Math.random();
                        //    series.addPoint([x, y], true, true);
                        //}, 1000);
                    }
                }
            },
            credits: { enabled: false },
            exporting: {
                enabled: false
            },
            navigator: {
                enabled: false
            },
            scrollbar: {
                enabled: false
            },
            rangeSelector: {
                enabled: false
            },
            loading: {
                style: {
                    backgroundColor: 'inherit',
                    opacity: 1
                }
            },
            xAxis: {
                lineColor: lineColor,
                tickColor: lineColor,
                type: 'datetime',
                tickPixelInterval: 70
            },
            yAxis: {
                tickColor: lineColor,
                gridLineColor: lineColor,
                title: {
                    text: 'Value'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: lineColor
                }]
            },
            tooltip: {
                shared: true,
                crosshairs: false,
                valueDecimals: 2,
                borderWidth: 0,
                backgroundColor: "rgba(0,0,0,0.2)",
                borderRadius: 2,
                style: {
                    color: "#cccccc",
                },
                shadow: !1,
                formatter: function () {
                    return Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
                        Highcharts.numberFormat(this.y, 2);
                }
            },
            series: [{
                name: 'Random data',
                data: data,
                lineWidth: 1,
                lineColor: '#e06c00',
            }]
        });

    }

    //设置市场价格
    setMarketPrice = function (data) {
        var marketPrice = (getContractType(data.GoodsID) == resources.ContractType.Buy ? data.buyPrice1 : data.sellPrice1).toFixed(2);

        //持仓明细
        var $cgoods = $objs.contract.find("td." + data.GoodsID);
        $cgoods.text(marketPrice);
        highlight($cgoods, marketPrice);

        getContractDataByGoods(data.GoodsID).forEach(function (contract) {
            contract.FloatingProfit = (contract.ContractType == resources.ContractType.Buy
                        ? (marketPrice - contract.Price) * contract.Quantity * contract.TradeSpec
                        : (contract.Price - marketPrice) * contract.Quantity * contract.TradeSpec);
            var $profit = $("#" + contract.ContractID).find("td.FloatingProfit");
            $profit.text(contract.FloatingProfit.toFixed(2));
            highlight($profit, contract.FloatingProfit * 1, 0);
        });

        //持仓汇总
        var $sgoods = $objs.contractSummary.find("td." + data.GoodsID);
        $sgoods.text(marketPrice);
        highlight($sgoods, marketPrice);

        var summary = getContractSummaryData(data.GoodsID);
        if (summary != null) {
            summary.FloatingProfit = (summary.ContractType == resources.ContractType.Buy
                            ? (marketPrice - summary.Price) * summary.Quantity * summary.TradeSpec
                            : (summary.Price - marketPrice) * summary.Quantity * summary.TradeSpec);
            var $sprofit = $("#cs" + summary.GoodsID).find("td.FloatingProfit");
            $sprofit.text(summary.FloatingProfit.toFixed(2));
            highlight($sprofit, summary.FloatingProfit * 1, 0);
        }

        //总浮动盈亏
        var totalFloatingProfit = 0;
        datas.contract.forEach(function (v) { totalFloatingProfit += v.FloatingProfit; });
        datas.account.FloatingProfit = totalFloatingProfit.toFixed(2) * 1;

        //设置交易窗口的现价
        if (datas.addOrder.GoodsID == data.GoodsID) {
            datas.addOrder.MarketPrice = getMarketPrice(null, data);
        }
    }

    //获得价格类型
    getOrderType = function () {
        return $("#setPrice").hasClass("active") ? resources.ContractOrderPriceType.LimitPrice : resources.ContractOrderPriceType.MarketPrice;
    }

    //获得持仓方向
    getContractType = function (goodsID) {
        var contract = getContractSummaryData(goodsID);
        return contract ? contract.ContractType : null;
    }

    //获得基础止损价
    getStopProfitPriceBase = function (type, data, marketPrice) {
        return (type == resources.ContractType.Buy ? marketPrice + data.ConditionPointDifference : marketPrice - data.ConditionPointDifference).toFixed(2);
    }

    //获得基础止盈价
    getStopLossPriceBase = function (type, data, marketPrice) {
        return (type == resources.ContractType.Buy ? marketPrice - data.ConditionPointDifference : marketPrice + data.ConditionPointDifference).toFixed(2);
    }

    //获得市场价格
    getMarketPrice = function (type, data) {
        type = type || datas.addOrder.Type;
        var diff = 0;// getOrderType() == resources.ContractOrderPriceType.MarketPrice ? 0 : data.Goods.PointDifference;
        var price = type == resources.ContractType.Buy ? data.sellPrice1 + diff : data.buyPrice1 - diff;
        console.log("PointDifference:" + data.Goods.PointDifference);
        return price.toFixed(2) * 1;
    }

    //获得最大可建仓数量
    getMaxUsableQty = function (orderPrice, goods) {
        var currentIncome = datas.account.CurrentIncome * 1 - datas.account.FrozenMoney * 1 - datas.account.FrozenFee * 1;
        var rate = datas.settings.MoneyRiskRate.MaxOpenPosition - (currentIncome <= 0 ? 0 : datas.account.UsedMoney / currentIncome);
        rate = rate > 0 ? rate : 0;
        var amount = currentIncome - (goods.FeeNumberType == 0 ? 0 : goods.FeeRate);//datas.account.AvailableMoney;
        var maxUsableQty = amount <= 0 ? 0 : (goods.TradeSpec <= 0 ? 0 : parseInt((amount) * rate / orderPrice / goods.TradeSpec / (goods.MoneyRate + (goods.FeeNumberType == 0 ? goods.FeeRate : 0))));
        return maxUsableQty > goods.MaxOrderQuantity ? goods.MaxOrderQuantity : maxUsableQty;
    }

    //获得委托数据通过状态
    getOrderByStatus = function (status) {
        if (!status) return null;
        var items = datas.order.filter(function (v) { return v.OrderStatus == status; });
        return items;
    }

    //获得行情数据
    getMarketData = function (goodsID) {
        if (!goodsID) return null;
        var items = datas.market.filter(function (v) { return v.GoodsID == goodsID; });
        return items.length > 0 ? items[0] : null;
    }

    getContractSummaryData = function (goodsID) {
        if (!goodsID) return null;
        var items = datas.contractSummary.filter(function (v) { return v.GoodsID == goodsID; });
        return items.length > 0 ? items[0] : null;
    }

    //获得持仓数据
    getContractDataByGoods = function (goodsID) {
        if (!goodsID) return null;
        var items = datas.contract.filter(function (v) { return v.GoodsID == goodsID; });
        return items;
    }

    //获得持仓数据
    getContractData = function (contractID) {
        if (!contractID) return null;
        var items = datas.contract.filter(function (v) { return v.ContractID == contractID; });
        return items.length > 0 ? items[0] : null;
    }

    //获得可用保证金
    getAvailableMoney = function (account) {
        return (account.LastIncome - account.UsedMoney - account.FrozenMoney - account.FrozenFee + account.TodayInMoney - account.TodayOutMoney + account.TodayProfit - account.TodayFee - account.LastDelayFee + account.FloatingProfit).toFixed(2) * 1;
    }

    //获得当前权益
    getCurrentIncome = function (account) {
        return (getAvailableMoney(account) + account.UsedMoney + account.FrozenMoney + account.FrozenFee).toFixed(2) * 1;
    }

    //获得风险率
    getMoneyRisk = function (account) {
        return account.UsedMoney / account.CurrentIncome;
    }

    priceColor = function ($obj, price1, price2) {
        if (price1 > price2) {
            $obj.removeClass("up").removeClass("dn").addClass("up");
        }
        else {
            $obj.removeClass("up").removeClass("dn").addClass("dn");
        }
    }

    //高亮颜色
    highlight = function ($obj, price1, price2) {
        $obj.addClass("light").animate({ opacity: 1 }, 500, function () {
            $(this).removeClass("light");
            price2 != null && priceColor($obj, price1, price2);
        });
    }

    //更新数据集
    updateData = function (list, item, id) {
        var r = list.filter(function (v) { return v[id] == item[id]; });
        if (r.length > 0) {
            $.extend(r[0], item);
        }
        else {
            list.push(item);
        }
    }

    //删除数组元素
    removeArrayItem = function (arr, idName, idValue) {
        var r = arr.filter(function (v) { return v[idName] == idValue; });
        r.length > 0 && arr.splice($.inArray(r[0], arr), 1);
    }

    //推送行情
    pushMarket = function (data) {
        //console.log("pushMarket");
        //console.log(data);
        if (data && $("#" + data.GoodsID).length > 0) {
            var $ID = $("#" + data.GoodsID);
            var $buyPrice1 = $ID.find(".buyPrice"), $sellPrice1 = $ID.find(".sellPrice"), $high = $ID.find(".high"), $low = $ID.find(".low"), $createTime = $ID.find(".createTime");
            var lastData = getMarketData(data.GoodsID);

            if (!lastData) return;

            $buyPrice1.text(data.buyPrice1.toFixed(2));
            $sellPrice1.text(data.sellPrice1.toFixed(2));
            $high.text(data.high.toFixed(2));
            $low.text(data.low.toFixed(2));
            $createTime.text(new Date(data.createTime).format("yyyy-MM-dd hh:mm:ss"));

            highlight($buyPrice1, lastData.buyPrice1, data.buyPrice1);
            highlight($sellPrice1, lastData.sellPrice1, data.sellPrice1);

            $.extend(lastData, data);

            setMarketPrice(lastData);

            refreshChart(lastData);
        }
    }

    pushAccount = function (item) {
        $.extend(datas.account, item);
        $.extend(datas.account, { MoneyRiskPercent: (datas.account.MoneyRisk * 100).toFixed(2), TodayInOutMoney: (datas.account.TodayInMoney - datas.account.TodayOutMoney).toFixed(2) });
    }

    pushOrder = function (item) {
        if (!item) return;
        if ($("#" + item.OrderID).length > 0) {
            $("#" + item.OrderID).remove();
        }

        updateData(datas.order, item, "OrderID");

        var arr = [];
        arr.push(item);
        if (item.OrderStatus == resources.ContractOrderStatus.Ordering) {
            $objs.ordering.prepend(parseTemplate(templates.order, { data: arr }));
        }
        else if (item.OrderStatus == resources.ContractOrderStatus.Ordered) {
            $objs.ordered.prepend(parseTemplate(templates.order, { data: arr }));
        }
        else if (item.OrderStatus == resources.ContractOrderStatus.Cancel) {
            $objs.orderCancel.prepend(parseTemplate(templates.order, { data: arr }));
        }
    }

    pushContract = function (item) {
        if (!item) return;
        if ($("#" + item.ContractID).length > 0) {
            $("#" + item.ContractID).remove();
        }

        updateData(datas.contract, item, "ContractID");
        if (item.Quantity > 0) {
            var arr = [];
            arr.push(item);
            $objs.contract.prepend(parseTemplate(templates.contract, { data: arr }));
        }
    }

    pushContractSummary = function (item) {
        if (!item) return;
        if ($("#cs" + item.GoodsID).length > 0) {
            $("#cs" + item.GoodsID).remove();
        }

        updateData(datas.contractSummary, item, "GoodsID");
        if (item.Quantity > 0) {
            var arr = [];
            arr.push(item);
            $objs.contractSummary.prepend(parseTemplate(templates.contractSummary, { data: arr }));
        }
    }

    //初始化数据
    loadInitData = function (data) {
        console.log(data);
        console.log(data.Account.FloatingProfit);

        datas.settings = data.Settings;
        datas.account = data.Account;
        datas.market = data.ListMarket || [];
        datas.order = data.ListOrder || [];
        datas.contract = data.ListContract || [];
        datas.contractSummary = data.ListContractSummary || [];

        $objs.openOrder.IsConfirmOrder.prop("checked", datas.settings.IsConfirmOrder);

        $objs.market.html(parseTemplate(templates.market, { data: datas.market }));
        $objs.ordering.html(parseTemplate(templates.order, { data: getOrderByStatus(resources.ContractOrderStatus.Ordering) }));
        $objs.ordered.html(parseTemplate(templates.order, { data: getOrderByStatus(resources.ContractOrderStatus.Ordered) }));
        $objs.orderCancel.html(parseTemplate(templates.order, { data: getOrderByStatus(resources.ContractOrderStatus.Cancel) }));
        $objs.contract.html(parseTemplate(templates.contract, { data: datas.contract }));
        $objs.contractSummary.html(parseTemplate(templates.contractSummary, { data: datas.contractSummary }));

        $.extend(datas.account, { MoneyRiskPercent: (datas.account.MoneyRisk * 100).toFixed(2), TodayInOutMoney: (datas.account.TodayInMoney - datas.account.TodayOutMoney).toFixed(2) });
        DataBind.bind($objs.account, datas.account).watch(function (ev) {
            switch (ev.data.key) {
                case "FloatingProfit":
                    if (ev.data.oldValue != ev.data.newValue) {
                        datas.account.AvailableMoney = getAvailableMoney(datas.account);
                        datas.account.CurrentIncome = getCurrentIncome(datas.account);
                        datas.account.MoneyRisk = getMoneyRisk(datas.account);
                        datas.account.MoneyRiskPercent = (datas.account.MoneyRisk * 100).toFixed(2);
                    }
                    $(this).removeClass().addClass(resources.GetMoneyColor(ev.data.newValue));
                    break;
                case "MoneyRiskPercent":
                    if (ev.data.oldValue != ev.data.newValue) {
                        if (ev.data.newValue > 50) {
                            $(this).removeClass().addClass("dn");
                        }
                        else {
                            $(this).removeClass().removeClass();
                        }
                    }
                    break;
            }
        });
        initAccountUI();

        selectMarket(datas.market[0].GoodsID);

        loader.hide();
    }

    initSignalR = function () {
        $.extend(signalR.client, {
            pushMarket: function (data) {
                pushMarket(data);
            },
            pushAccount: function (data) {
                pushAccount(data);
            },
            pushOrder: function (data) {
                pushOrder(data);
            },
            pushContract: function (data) {
                pushContract(data);
            },
            pushContractSummary: function (data) {
                pushContractSummary(data);
            }
        });

        $.connection.hub.start().done(function () {
            signalR.server.loadInitData().done(function (data) {
                loadInitData(data);
            }).fail(function (error) {
                console.log('Invocation of loadInitData failed. Error: ' + error);
            });
        });

    }


};